package com.mkx.core.monitor;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;
import java.lang.reflect.Method;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 系统负载监控器
 * 用于实时监控系统CPU使用率、内存占用等指标
 */
public class SystemLoadMonitor {

    private static final Logger logger = LoggerFactory.getLogger(SystemLoadMonitor.class);
    private static final SystemLoadMonitor INSTANCE = new SystemLoadMonitor();
    
    private final OperatingSystemMXBean osBean;
    private final ScheduledExecutorService scheduler;
    private final AtomicReference<SystemLoad> currentLoad;
    
    // 负载计算的采样窗口大小
    private static final int SAMPLE_WINDOW = 10;
    // CPU使用率历史数据
    private final double[] cpuUsageHistory;
    private int historyIndex;
    
    private SystemLoadMonitor() {
        this.osBean = ManagementFactory.getOperatingSystemMXBean();
        this.scheduler = Executors.newSingleThreadScheduledExecutor(r -> {
            Thread t = new Thread(r, "system-load-monitor");
            t.setDaemon(true);
            return t;
        });
        this.currentLoad = new AtomicReference<>(new SystemLoad(0, 0, 0));
        this.cpuUsageHistory = new double[SAMPLE_WINDOW];
        this.historyIndex = 0;
        
        // 启动监控线程，每5秒更新一次
        scheduler.scheduleAtFixedRate(this::updateSystemLoad, 0, 5, TimeUnit.SECONDS);
        
        // 添加JVM关闭钩子
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            scheduler.shutdown();
            try {
                scheduler.awaitTermination(1, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }));
    }
    
    /**
     * 获取单例实例
     */
    public static SystemLoadMonitor getInstance() {
        return INSTANCE;
    }
    
    /**
     * 更新系统负载信息
     */
    private void updateSystemLoad() {
        try {
            double cpuUsage = getCpuLoad();
            double memoryUsage = getMemoryUsage();
            int threadCount = getThreadCount();
            
            // 更新历史CPU使用率数据
            synchronized (cpuUsageHistory) {
                cpuUsageHistory[historyIndex] = cpuUsage;
                historyIndex = (historyIndex + 1) % SAMPLE_WINDOW;
            }
            
            currentLoad.set(new SystemLoad(cpuUsage, memoryUsage, threadCount));
            
            logger.debug("System load updated - CPU: {:.2f}%, Memory: {:.2f}%, Threads: {}",
                    cpuUsage * 100, memoryUsage * 100, threadCount);
            
        } catch (Exception e) {
            logger.warn("Failed to update system load metrics", e);
        }
    }
    
    /**
     * 获取CPU使用率
     */
    private double getCpuLoad() {
        try {
            // 使用反射获取CPU负载，兼容不同JVM实现
            Method getSystemCpuLoadMethod = osBean.getClass().getMethod("getSystemCpuLoad");
            getSystemCpuLoadMethod.setAccessible(true);
            Double cpuLoad = (Double) getSystemCpuLoadMethod.invoke(osBean);
            return cpuLoad != null && cpuLoad >= 0 ? cpuLoad : 0;
        } catch (Exception e) {
            logger.debug("Failed to get CPU load", e);
            return 0;
        }
    }
    
    /**
     * 获取内存使用率
     */
    private double getMemoryUsage() {
        try {
            Runtime runtime = Runtime.getRuntime();
            long totalMemory = runtime.totalMemory();
            long freeMemory = runtime.freeMemory();
            long usedMemory = totalMemory - freeMemory;
            return (double) usedMemory / totalMemory;
        } catch (Exception e) {
            logger.debug("Failed to get memory usage", e);
            return 0;
        }
    }
    
    /**
     * 获取当前线程数
     */
    private int getThreadCount() {
        return ManagementFactory.getThreadMXBean().getThreadCount();
    }
    
    /**
     * 获取当前系统负载
     */
    public SystemLoad getCurrentLoad() {
        return currentLoad.get();
    }
    
    /**
     * 获取平均CPU使用率（基于采样窗口）
     */
    public double getAverageCpuUsage() {
        synchronized (cpuUsageHistory) {
            double sum = 0;
            int validSamples = 0;
            for (double usage : cpuUsageHistory) {
                if (usage > 0) {
                    sum += usage;
                    validSamples++;
                }
            }
            return validSamples > 0 ? sum / validSamples : 0;
        }
    }
    
    /**
     * 获取系统负载等级
     */
    public LoadLevel getLoadLevel() {
        SystemLoad load = getCurrentLoad();
        
        // 综合CPU、内存和线程数评估负载等级
        if (load.cpuUsage > 0.8 || load.memoryUsage > 0.85) {
            return LoadLevel.HIGH;
        } else if (load.cpuUsage > 0.6 || load.memoryUsage > 0.7) {
            return LoadLevel.MEDIUM;
        } else {
            return LoadLevel.LOW;
        }
    }
    
    /**
     * 系统负载数据类
     */
    public static class SystemLoad {
        public final double cpuUsage;     // CPU使用率 (0.0-1.0)
        public final double memoryUsage;  // 内存使用率 (0.0-1.0)
        public final int threadCount;     // 当前线程数
        
        public SystemLoad(double cpuUsage, double memoryUsage, int threadCount) {
            this.cpuUsage = cpuUsage;
            this.memoryUsage = memoryUsage;
            this.threadCount = threadCount;
        }
    }
    
    /**
     * 负载等级枚举
     */
    public enum LoadLevel {
        LOW,
        MEDIUM,
        HIGH
    }
}